package org.charles.zhifou.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.Min;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.charles.zhifou.common.annotation.AuthCheck;
import org.charles.zhifou.common.response.BaseResponse;
import org.charles.zhifou.common.response.ResponseCodeEnum;
import org.charles.zhifou.common.response.ResponseUtils;
import org.charles.zhifou.enums.SqlSortOrderEnum;
import org.charles.zhifou.enums.UserRoleEnum;
import org.charles.zhifou.common.exception.ThrowUtils;
import org.charles.zhifou.model.dto.scoringResult.ScoringResultAddRequest;
import org.charles.zhifou.model.dto.scoringResult.ScoringResultEditRequest;
import org.charles.zhifou.model.dto.scoringResult.ScoringResultQueryRequest;
import org.charles.zhifou.model.dto.scoringResult.ScoringResultUpdateRequest;
import org.charles.zhifou.model.entity.ScoringResult;
import org.charles.zhifou.model.vo.ScoringResultVO;
import org.charles.zhifou.service.ScoringResultService;
import org.charles.zhifou.service.UserService;
import org.charles.zhifou.common.utils.SqlUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * <h1>评分结果接口</h1>
 *
 * @author charles
 * @version 1.0
 */
@RestController
@RequestMapping("/scoringResult")
@Slf4j
@Tag(name = "评分结果接口")
public class ScoringResultController {

    @Resource
    private ScoringResultService scoringResultService;

    @Resource
    private UserService userService;

    // region 增删改查

    /**
     * 创建评分结果
     *
     * @param scoringResultAddRequest 创建请求
     * @return 新写入的数据 id
     */
    @PostMapping("/add")
    @Operation(summary = "创建评分结果")
    public BaseResponse<Long> addScoringResult(@Validated @RequestBody ScoringResultAddRequest scoringResultAddRequest) {
        // 封装参数
        ScoringResult scoringResult = new ScoringResult();
        scoringResult.setId(null);
        scoringResult.setResultName(scoringResultAddRequest.getResultName());
        scoringResult.setResultDesc(scoringResultAddRequest.getResultDesc());
        scoringResult.setResultPicture(scoringResultAddRequest.getResultPicture());
        scoringResult.setResultProp(JSONUtil.toJsonStr(scoringResultAddRequest.getResultProp()));
        scoringResult.setResultScoreRange(scoringResultAddRequest.getResultScoreRange());
        scoringResult.setAppId(scoringResultAddRequest.getAppId());
        scoringResult.setUserId(userService.getLoginUser().getId());
        
        // 写入并返回 id
        Long newScoringResultId = scoringResultService.saveScoringResult(scoringResult);
        return ResponseUtils.success(newScoringResultId);
    }

    /**
     * 删除评分结果
     *
     * @param id 评分结果 id
     * @return 是否删除成功
     */
    @DeleteMapping("/delete")
    @Operation(summary = "删除评分结果")
    public BaseResponse<Boolean> deleteScoringResultById(
            @Min(value = 1, message = "id 必须大于 0")
            Long id
    ) {
        Boolean isSuccessful = scoringResultService.removeScoringResultById(id);
        return ResponseUtils.success(isSuccessful);
    }

    /**
     * 更新评分结果 (仅管理员)
     *
     * @param scoringResultUpdateRequest 更新请求
     * @return 是否更新成功
     */
    @PostMapping("/update")
    @AuthCheck(neededRole = UserRoleEnum.ADMIN)
    @Operation(summary = "更新评分结果")
    public BaseResponse<Boolean> updateScoringResultById(@Validated @RequestBody ScoringResultUpdateRequest scoringResultUpdateRequest) {
        // 封装参数
        ScoringResult scoringResult = new ScoringResult();
        scoringResult.setId(scoringResultUpdateRequest.getId());
        scoringResult.setResultName(scoringResultUpdateRequest.getResultName());
        scoringResult.setResultDesc(scoringResultUpdateRequest.getResultDesc());
        scoringResult.setResultPicture(scoringResult.getResultPicture());
        scoringResult.setResultProp(JSONUtil.toJsonStr(scoringResultUpdateRequest.getResultProp()));
        scoringResult.setResultScoreRange(scoringResult.getResultScoreRange());
        scoringResult.setAppId(null);
        scoringResult.setUserId(null);

        Boolean isSuccessful = scoringResultService.updateScoringResultById(scoringResult);
        return ResponseUtils.success(isSuccessful);
    }

    /**
     * 根据 id 获取评分结果 VO
     *
     * @param id 评分结果 id
     * @return 评分结果 VO
     */
    @GetMapping("/get_vo")
    @Operation(summary = "根据 id 获取评分结果 VO")
    public BaseResponse<ScoringResultVO> getScoringResultVOById(
            @Min(value = 1, message = "id 必须大于 0")
            Long id
    ) {
        // 查询数据库
        ScoringResult scoringResult = scoringResultService.getById(id);
        ThrowUtils.throwIf(scoringResult == null, ResponseCodeEnum.NOT_FOUND_ERROR, "查询的评分结果不存在");

        ScoringResultVO scoringResultVO = ScoringResultVO.entityToVo(scoringResult);
        return ResponseUtils.success(scoringResultVO);
    }

    /**
     * 分页获取评分结果列表 (仅管理员)
     *
     * @param scoringResultQueryRequest 查询请求
     * @return 分页评分结果列表
     */
    @PostMapping("/list/page")
    @AuthCheck(neededRole = UserRoleEnum.ADMIN)
    @Operation(summary = "分页获取评分结果列表 (仅管理员)")
    public BaseResponse<Page<ScoringResult>> listScoringResultByPage(@Validated @RequestBody ScoringResultQueryRequest scoringResultQueryRequest) {
        // 分页参数
        long current = scoringResultQueryRequest.getCurrent();
        long size = scoringResultQueryRequest.getPageSize();

        // 查询数据库
        Page<ScoringResult> scoringResultPage = scoringResultService.page(new Page<>(current, size), buildQueryWrapper(scoringResultQueryRequest));
        return ResponseUtils.success(scoringResultPage);
    }

    /**
     * 分页获取评分结果列表 VO
     *
     * @param scoringResultQueryRequest 查询请求
     * @return 分页评分结果 VO 列表
     */
    @PostMapping("/list/page_vo")
    @Operation(summary = "分页获取评分结果列表 VO")
    public BaseResponse<Page<ScoringResultVO>> listScoringResultVOByPage(@Validated @RequestBody ScoringResultQueryRequest scoringResultQueryRequest) {
        // 分页参数
        long current = scoringResultQueryRequest.getCurrent();
        long size = scoringResultQueryRequest.getPageSize();

        // 查询数据库并封装返回
        Page<ScoringResult> scoringResultPage = scoringResultService.page(new Page<>(current, size), buildQueryWrapper(scoringResultQueryRequest));
        Page<ScoringResultVO> scoringResultVOPage = new Page<>(current, size, scoringResultPage.getTotal());
        scoringResultVOPage.setRecords(scoringResultPage.getRecords().stream().map(ScoringResultVO::entityToVo).toList());
        return ResponseUtils.success(scoringResultVOPage);
    }

    /**
     * 分页获取当前登录用户创建的评分结果列表
     *
     * @param scoringResultQueryRequest 查询请求
     * @return 分页评分结果 VO 列表
     */
    @PostMapping("/my/list/page_vo")
    @Operation(summary = "分页获取当前登录用户创建的评分结果列表")
    public BaseResponse<Page<ScoringResultVO>> listMyScoringResultVOByPage(@Validated @RequestBody ScoringResultQueryRequest scoringResultQueryRequest) {
        // 分页参数
        long current = scoringResultQueryRequest.getCurrent();
        long size = scoringResultQueryRequest.getPageSize();

        // 补充用户信息
        scoringResultQueryRequest.setUserId(userService.getLoginUser().getId());

        // 查询数据库并封装返回
        Page<ScoringResult> scoringResultPage = scoringResultService.page(new Page<>(current, size), buildQueryWrapper(scoringResultQueryRequest));
        Page<ScoringResultVO> scoringResultVOPage = new Page<>(current, size, scoringResultPage.getTotal());
        scoringResultVOPage.setRecords(scoringResultPage.getRecords().stream().map(ScoringResultVO::entityToVo).toList());
        return ResponseUtils.success(scoringResultVOPage);
    }

    /**
     * 编辑评分结果
     *
     * @param scoringResultEditRequest 编辑评分结果请求
     * @return 是否编辑成功
     */
    @PostMapping("/edit")
    @Operation(summary = "编辑评分结果")
    public BaseResponse<Boolean> editScoringResult(@Validated @RequestBody ScoringResultEditRequest scoringResultEditRequest) {
        // 封装参数
        ScoringResult scoringResult = new ScoringResult();
        scoringResult.setId(scoringResultEditRequest.getId());
        scoringResult.setResultName(scoringResultEditRequest.getResultName());
        scoringResult.setResultDesc(scoringResultEditRequest.getResultDesc());
        scoringResult.setResultPicture(scoringResultEditRequest.getResultPicture());
        scoringResult.setResultProp(JSONUtil.toJsonStr(scoringResultEditRequest.getResultProp()));
        scoringResult.setResultScoreRange(scoringResultEditRequest.getResultScoreRange());
        scoringResult.setAppId(null);
        scoringResult.setUserId(null);

        Boolean isSuccessful = scoringResultService.editScoringResultById(scoringResult);
        return ResponseUtils.success(isSuccessful);
    }

    // endregion

    public static QueryWrapper<ScoringResult> buildQueryWrapper(ScoringResultQueryRequest scoringResultQueryRequest) {
        QueryWrapper<ScoringResult> queryWrapper = new QueryWrapper<>();
        if (scoringResultQueryRequest == null) {
            return queryWrapper;
        }
        // 从对象中取值
        Long id = scoringResultQueryRequest.getId();
        String resultName = scoringResultQueryRequest.getResultName();
        String resultDesc = scoringResultQueryRequest.getResultDesc();
        String resultPicture = scoringResultQueryRequest.getResultPicture();
        String resultProp = scoringResultQueryRequest.getResultProp();
        Integer resultScoreRange = scoringResultQueryRequest.getResultScoreRange();
        Long appId = scoringResultQueryRequest.getAppId();
        Long userId = scoringResultQueryRequest.getUserId();
        Long notId = scoringResultQueryRequest.getNotId();
        String searchText = scoringResultQueryRequest.getSearchText();
        String sortField = StrUtil.toUnderlineCase(scoringResultQueryRequest.getSortField());
        SqlSortOrderEnum sortOrder = scoringResultQueryRequest.getSortOrder();

        // 补充需要的查询条件
        // 从多字段中搜索
        if (StringUtils.isNotBlank(searchText)) {
            // 需要拼接查询条件
            queryWrapper.and(qw -> qw.like("result_name", searchText).or().like("result_desc", searchText));
        }
        // 模糊查询
        queryWrapper.like(StringUtils.isNotBlank(resultName), "result_name", resultName);
        queryWrapper.like(StringUtils.isNotBlank(resultDesc), "result_desc", resultDesc);
        queryWrapper.like(StringUtils.isNotBlank(resultProp), "result_prop", resultProp);
        // 精确查询
        queryWrapper.ne(ObjectUtils.isNotEmpty(notId), "id", notId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "user_id", userId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(appId), "app_id", appId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(resultScoreRange), "result_score_range", resultScoreRange);
        queryWrapper.eq(StringUtils.isNotBlank(resultPicture), "result_picture", resultPicture);
        // 排序规则
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), !SqlSortOrderEnum.DESC.equals(sortOrder), sortField);

        return queryWrapper;
    }
}
